package com.xhu.util;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

/**
 * 二进制字符串转换工具类
 * @Auth zongf
 * @Date 2019-05-07
 */
public class BinaryStringConverteUtil {

    private static final String BIN_SEPARATOR = "";


    /**
     * 字符串转换为二进制字符串
     * @param str 普通字符串
     * @return String 二进制字符串
     * @Auth zongf
     * @Date 2019-05-07
     */
    public static String toBinaryString(String str) {
        //参数校验
        if (str == null) return null;

        StringBuffer sb = new StringBuffer();
        //将str转化为byte数组
        byte[] bytes = str.getBytes();
        for (byte aByte : bytes) {
            //将单个byte转化为二进制字符串
            String binaryTemp = Integer.toBinaryString(aByte);
            StringBuffer padding = new StringBuffer();
            //检查binaryTemp是否长度为8位,否则用0填充到8位
            for (int i=0; i<8-binaryTemp.length();i++){
                padding.append(0);
            }
            sb.append(padding+binaryTemp);
        }
        return sb.toString();
    }


    /**
     * 二进制字符串转换为普通字符串
     * @param binaryStr 二进制字符串
     * @return String 普通字符串
     * @Auth zongf
     * @Date 2019-05-07
     */
    public static String toString(String binaryStr) {
        //参数校验
        if (binaryStr == null) return null;
        //以每8位将字符串分割
        List<String> binList = new ArrayList<>();
        for (int i=0; i<binaryStr.length()/8; i++){
            binList.add(binaryStr.substring(i*8,(i+1)*8));
        }


        StringBuffer sb = new StringBuffer();
        for (String binStr : binList) {
            char c = binstrToChar(binStr);
            sb.append(c);
        }
        return sb.toString();
    }

    /**
     * 统计二进制字符串中1的个数
     * @param binaryStr 二进制字符，如:1101
     * @return int
     * @Auth zongf
     * @Date 2019-05-07
     */
    public static int countBitOne(String binaryStr) {
        int cnt = 0;
        if(binaryStr != null) {
            byte[] bytes = binaryStr.getBytes();
            for (byte aByte : bytes) {
                if (aByte==49) {
                    cnt++;
                }
            }
        }
        return cnt;
    }

    /**
     * 二进制字符转换为int数组
     * @param binStr 二进制字符串
     * @return int[]
     * @Auth zongf
     * @Date 2019-05-07
     */
    private static int[] binstrToIntArray(String binStr) {
        char[] temp=binStr.toCharArray();
        int[] result=new int[temp.length];
        for(int i=0;i<temp.length;i++) {
            result[i]=temp[i]-48;
        }
        return result;
    }

    /**
     * 将二进制转换成字符
     * @param binStr 二进制字符串
     * @return char
     * @Auth zongf
     * @Date 2019-05-07
     */
    private static char binstrToChar(String binStr){
        int[] temp=binstrToIntArray(binStr);
        int sum=0;
        for(int i=0; i<temp.length;i++){
            sum +=temp[temp.length-1-i]<<i;
        }
        return (char)sum;
    }


    public static void main(String[] args) throws UnsupportedEncodingException {

        // 使用基本编码
        String base64encodedString = Base64.getEncoder().encodeToString("冉朝聪".getBytes(StandardCharsets.UTF_8));
        System.out.println("Base64 编码字符串 (基本) :" + base64encodedString);

        String str = base64encodedString;

        // 转换为二进制字符串
        String binaryStr = BinaryStringConverteUtil.toBinaryString(str);

        // 反向转换
        String newStr = BinaryStringConverteUtil.toString(binaryStr);

        // 解码
        byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);



        System.out.println("源字符串:" + str);
        System.out.println("二进制字符串:" + binaryStr);
        System.out.println("新字符串:" + newStr);
        System.out.println("原始字符串: " + new String(base64decodedBytes, "utf-8"));
    }


}

